102.変数ベースの2キャラ(CRAZY)

2つのキャラを変数ベースで管理すると、コードの重複が発生します。

p5.js oop
Learning OOP Object Oriented Programming

2つの異なる形状(円と四角)を動かすために、変数を2セット用意しています。

問題点: コードの重複

  • x, y, xSpeed, ySpeed, accelerationx2, y2, xSpeed2, ySpeed2, acceleration2
  • prepare()prepare2()
  • update()update2()
  • display()display2()

すべてが2倍になっています。3つ目のキャラを追加したければ、さらに同じコードをコピーペーストして x3, y3... と増やす必要があります。

これはDRY原則(Don't Repeat Yourself)に反しています。

View Source Code

let W, H, PW, PH;
const PADDING_RATIO = 0.2;
const MAX_SPEED = 10;

let x, y, xSpeed, ySpeed, acceleration;
let x2, y2, xSpeed2, ySpeed2, acceleration2;

function prepare() {
  x = random(width);
  y = random(height);
  xSpeed = (Math.random() - 0.5) * MAX_SPEED;
  ySpeed = (Math.random() - 0.5) * MAX_SPEED;
  acceleration = 0.1;
}

function prepare2() {
  x2 = random(width);
  y2 = random(height);
  xSpeed2 = (Math.random() - 0.5) * MAX_SPEED;
  ySpeed2 = (Math.random() - 0.5) * MAX_SPEED;
  acceleration2 = 0.1;
}

function update() {
  x += xSpeed;
  y += ySpeed;

  if (x < 0 + PW) {
    xSpeed += acceleration;
  } else if (x > W - PW) {
    xSpeed -= acceleration;
  }

  if (y < 0 + PH) {
    ySpeed += acceleration;
  } else if (y > H - PH) {
    ySpeed -= acceleration;
  }
}

function update2() {
  x2 += xSpeed2;
  y2 += ySpeed2;

  if (x2 < 0 + PW) {
    xSpeed2 += acceleration2;
  } else if (x2 > W - PW) {
    xSpeed2 -= acceleration2;
  }

  if (y2 < 0 + PH) {
    ySpeed2 += acceleration2;
  } else if (y2 > H - PH) {
    ySpeed2 -= acceleration2;
  }
}

function display() {
  stroke(0);
  fill(0);
  ellipse(x, y, 10, 10);
  text(["1:", Math.floor(x), Math.floor(y)], x + 10, y + 10);
}

function display2() {
  stroke(0);
  fill(0);
  rectMode(CENTER);
  rect(x2, y2, 10, 10);
  text(["2:", Math.floor(x2), Math.floor(y2)], x2 + 20, y2 + 20);
}

// main

function setup() {
  createCanvas((W = windowWidth), (H = windowHeight));
  PW = W * PADDING_RATIO;
  PH = H * PADDING_RATIO;

  prepare();
  prepare2();
}

function draw() {
  background(255);

  update();
  update2();

  display();
  display2();
}